#ifndef TESTRUNNER_HPP_
# define TESTRUNNER_HPP_

# include <list>
# include <string>
# include <utility>
# include "TestFailureException.hpp"

namespace unit_test {

/*! \class TestRunner
 * \brief Handle the tests cases
 *
 * This class provide the main implementation for the unit testing suite
 */
class TestRunner {
  typedef void (CaseFunction)(void);

public:
  /*! Constructor */
  TestRunner(const std::string &suiteName = "Test suite");
  /*! Copy constructor
   * \param from : A reference on the TestRunner object to copy
   */
  TestRunner(const TestRunner &from);
  /*! Destructor */
  ~TestRunner();

  /*! Assignment operator overload
   * \param from : A reference on the TestRunner object to copy
   */
  TestRunner &operator=(const TestRunner &);

  /*! Run all tests and summarise
   * \param verbose : If true, print one message per test (failed or passed)
   */
  void Run(bool verbose = false);
  /*! Add the given function to the test suite
   * \param ... : various information about the test case,
   * use #UTESTS_MAKE_CASE_DATA(functionPtr)
   */
  void AddTestCase(const std::string &file, unsigned int line,
      const std::string &name, CaseFunction *function);

private:
  /*! \struct TestCasesData
   * This structure contains various informations about a test cases function
   */
  struct TestCasesData {
    CaseFunction *function; /*!< A pointer on the test case's function */
    std::string name; /*!< The test case name */
    std::string file; /*!< The file where it's been implemented */
    unsigned int line; /*!< The line where it's been implemented in this file */
  };

  /*! Start the specified test case
   * \param data : the test case's data
   */
  void StartTestCase(const TestCasesData &data);

  std::list<TestCasesData> mCaseFunctionsList;
  /*!< A list containing all the suite's test cases functions given by the user */
  unsigned int mPassedCount; /*!< Failed tests counter */
  unsigned int mFailedCount; /*!< Failed tests counter */
  std::string mSuiteName; /*!< The suite name */
};

} /* !namespace unit_test */

#endif /* !TESTRUNNER_HPP_ */
